﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ReadyApps.Wiki;
using System.Web.Routing;
using System.Web;
using ReadyApps.Common.Exceptions;

namespace ReadyAppsTest.Wiki
{
    /// <summary>
    /// Summary description for WikiUrlManagerTest
    /// </summary>
    [TestClass]
    public class WikiUrlManagerTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Constructor Tests

        [TestMethod]
        [Description("Tests the constructor for proper instantiation")]
        public void WikiUrlManagerConstructorTest()
        {
            string baseFolder = "/base/";
            Route route = new Route("wiki/{*path}", null);
            WikiUrlManager target = new WikiUrlManager(baseFolder, route);
            PrivateObject targetWrapper = new PrivateObject(target);
            Assert.AreEqual(baseFolder, (string)targetWrapper.GetField("baseFolder"));
            Assert.AreEqual(1, ((RouteCollection)targetWrapper.GetField("routes")).Count);
            Assert.AreSame(route, ((RouteCollection)targetWrapper.GetField("routes"))[0]);
        }

        [TestMethod]
        [Description("Tests failure of passing a null for the baseFolder parameter")]
        [ExpectedException(typeof(ArgumentNullException))]
        public void WikiUrlManagerConstructorNullBaseFolderTest()
        {
            string baseFolder = null;
            Route route = new Route("wiki/{*path}", null);
            WikiUrlManager target = new WikiUrlManager(baseFolder, route);
        }

        [TestMethod]
        [Description("Tests failure of passing a null for the route parameter")]
        [ExpectedException(typeof(ArgumentNullException))]
        public void WikiUrlManagerConstructorNullRouteTest()
        {
            string baseFolder = "/base/";
            Route route = null;
            WikiUrlManager target = new WikiUrlManager(baseFolder, route);
        }

        [TestMethod]
        [Description("Tests failure of passing an empty string for the baseFolder parameter")]
        [ExpectedException(typeof(ArgumentNullException))]
        public void WikiUrlManagerConstructorEmptyBaseFolderTest()
        {
            string baseFolder = string.Empty;
            Route route = new Route("wiki/{*path}", null);
            WikiUrlManager target = new WikiUrlManager(baseFolder, route);
        }

        #endregion

        #region GetVirtualUrl Tests

        [TestMethod]
        [Description("Tests a set of paths to ensure the proper mapping of paths")]
        public void GetVirtualUrlValidTest()
        {
            HttpContext.Current = new HttpContext(new HttpRequest("~/test.aspx", "http://server/test.aspx", null), new HttpResponse(null));
            PageRouteHandler handler = new PageRouteHandler("~/test.aspx");

            List<Tuple<string, string, string, string>> data = new List<Tuple<string, string, string, string>>();
            data.Add(new Tuple<string, string, string, string>("/", "wiki/{*path}", "/page", "/wiki/page"));
            data.Add(new Tuple<string, string, string, string>("/", "wiki/{*path}", "/folder/page", "/wiki/folder/page"));
            data.Add(new Tuple<string, string, string, string>("/base/", "wiki/{*path}", "/base/page", "/wiki/page"));
            data.Add(new Tuple<string, string, string, string>("/base/", "wiki/{*path}", "/base/folder/page", "/wiki/folder/page"));

            WikiUrlManager target;
            string actual;
            foreach (var row in data)
            {
                target = new WikiUrlManager(row.Item1, new Route(row.Item2, handler));
                actual = target.GetVirtualUrl(row.Item3);
                Assert.AreEqual(row.Item4, actual, string.Format("Failed on input baseFolder=|{0}|, routeUrl=|{1}|, trial=|{2}|",
                    row.Item1, row.Item2, row.Item3));
            }
        }

        [TestMethod]
        [Description("Tests trying to generate a URL to a location higher up the folder hierarchy")]
        [ExpectedException(typeof(UnreachableFolderException))]
        public void GetVirtualUrlUnreachableTest()
        {
            HttpContext.Current = new HttpContext(new HttpRequest("~/test.aspx", "http://server/test.aspx", null), new HttpResponse(null));
            PageRouteHandler handler = new PageRouteHandler("~/test.aspx");
            WikiUrlManager target = new WikiUrlManager("/base/", new Route("wiki/{*path}", handler));
            target.GetVirtualUrl("/page");
        }

        [TestMethod]
        [Description("Tests trying to generate a URL to a location in a different folder hierarchy")]
        [ExpectedException(typeof(ArgumentException))]
        public void GetVirtualUrlDifferentHierarchyTest()
        {
            HttpContext.Current = new HttpContext(new HttpRequest("~/test.aspx", "http://server/test.aspx", null), new HttpResponse(null));
            PageRouteHandler handler = new PageRouteHandler("~/test.aspx");
            WikiUrlManager target = new WikiUrlManager("/base/", new Route("wiki/{*path}", handler));
            target.GetVirtualUrl("/other/page");
        }

        #endregion
    }
}
